package com.augurit.wf.bi.service.impl;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpSession;
import com.augurit.common.system.web.auth.form.LoginUserForm;
import org.apache.struts2.ServletActionContext;
import org.hibernate.Query;
import org.hibernate.SQLQuery;
import org.jbpm.pvm.internal.model.ProcessDefinitionImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.augurit.common.constant.OrgConstant;
import com.augurit.common.sysmeta.service.ISysMetaTableService;
import com.augurit.common.sysmeta.web.form.SysMetaTableForm;
import com.augurit.common.system.util.WebContextUtils;
import com.augurit.common.util.PageUtils;
import com.augurit.common.util.HqlUtils;
import com.augurit.common.util.lang.StringUtils;
import com.augurit.wf.bi.convert.WfActElemPrivDefConvertor;
import com.augurit.wf.bi.convert.WfActPrinttplPrivDefConvertor;
import com.augurit.wf.bi.convert.WfBusTemplateConvertor;
import com.augurit.wf.bi.convert.WfPageElementConvertor;
import com.augurit.wf.bi.service.IWfActElemPrivDefService;
import com.augurit.wf.bi.service.IWfBusTemplateService;
import com.augurit.wf.bi.service.IWfPageElementService;
import com.augurit.wf.bi.service.IWfTemplateAttachmentRefService;
import com.augurit.wf.bi.web.form.WfActElemPrivDefForm;
import com.augurit.wf.bi.web.form.WfBusInstanceTaskForm;
import com.augurit.wf.bi.web.form.WfBusTemplateForm;
import com.augurit.wf.bi.web.form.WfPageElementForm;
import com.augurit.wf.bi.web.form.WfPrivControlForm;
import com.augurit.wf.common.dao.WfActElemPrivDefDao;
import com.augurit.wf.common.dao.WfBusInstanceDao;
import com.augurit.wf.common.dao.WfBusTemplateDao;
import com.augurit.wf.common.dao.WfPageElementDao;
import com.augurit.wf.common.dao.WfTemplateElementRefDao;
import com.augurit.wf.common.dao.WfViewConfigDao;
import com.augurit.wf.common.entity.WfActElemPrivDef;
import com.augurit.wf.common.entity.WfActPrinttplPrivDef;
import com.augurit.wf.common.entity.WfBusTemplate;
import com.augurit.wf.common.entity.WfPageElement;
import com.augurit.wf.common.entity.WfTemplateElementRef;
import com.augurit.wf.common.service.IWfService;
import com.augurit.wf.common.util.WfUtils;

import org.springside.modules.orm.PropertyFilter;
import org.springside.modules.orm.Page;
import org.springside.modules.web.struts2.Struts2Utils;

@Service("wfBusTemplateServiceImpl")
@Transactional
public class WfBusTemplateServiceImpl implements IWfBusTemplateService{

	private static final String GET_ELEMENTS_BY_TYPE = "select elem from WfBusTemplate temp, WfTemplateElementRef ref, WfPageElement elem where temp.id=ref.templateId and ref.elementId=elem.id and elem.elementType=?";
	//private static final String GET_WHOLE_TEMPLATE_INFO = "select template, type.templateTypeName from WfBusTemplate template, WfBusTemplateType type where template.templateTypeId=type.id and template.isActive='1'";
	//城管委审批修改
	private static final String GET_WHOLE_TEMPLATE_INFO = "select template, type.templateTypeName from WfBusTemplate template, WfBusTemplateType type where template.templateTypeId=type.id ";
	
	
	@Autowired
	private WfBusTemplateDao wfBusTemplateDao;
	
	@Autowired
	private WfTemplateElementRefDao wfTemplateElementRefDao;
	
	@Autowired
	private WfPageElementDao wfPageElementDao;
	
	@Autowired
	private WfActElemPrivDefDao wfActElemPrivDefDao;
	
	@Autowired
	private WfBusInstanceDao wfBusInstanceDao;
	
	@Autowired
	private WfViewConfigDao wfViewConfigDao;
	
	@Autowired
	private IWfPageElementService wfPageElementService;
	
	@Autowired
	private IWfActElemPrivDefService wfActElemPrivDefService;
	
	@Autowired
	private IWfTemplateAttachmentRefService wfTemplateAttachmentRefService;
	
	@Autowired
	private ISysMetaTableService sysMetaTableService;
	
	@Autowired
	private IWfService wfService;
	
	/**
	 * 根据主键获取Form对象
	 */
	@Transactional(readOnly = true)
	public WfBusTemplateForm get(Long id) {
		WfBusTemplate entity = wfBusTemplateDao.get(id);
		return WfBusTemplateConvertor.convertVoToForm(entity);
	}
	
	@Transactional(readOnly = true)
	public WfBusTemplateForm getByTemplateName(String templateName) {
		String hql = "from WfBusTemplate ps where ps.templateName=?";
		WfBusTemplate entity = wfBusTemplateDao.findUnique(hql, templateName);
		return WfBusTemplateConvertor.convertVoToForm(entity);
	}
	
	/**
	 * 根据主键获取Form对象(主键不存在时候不报异常)
	 */
	@Transactional(readOnly = true)
	public WfBusTemplateForm findById(Long id) {
		WfBusTemplateForm form=null;
		String hql="from WfBusTemplate where id=?";
		List<WfBusTemplate> list=wfBusTemplateDao.find(hql, id);
		if(list!=null&&list.size()>0){
			WfBusTemplate template=list.get(0);
			form=WfBusTemplateConvertor.convertVoToForm(template);
		}
		return form;
	}
	
	/**
	 * 删除Form对象列表
	 */
	public void delete(Long... ids) {
		wfBusTemplateDao.delete(ids);
	}
	
	/**
	 * 保存新增或修改的Form对象列表
	 */
	public void save(WfBusTemplateForm... forms) {
		if(forms != null){
			for(WfBusTemplateForm form : forms){
				setCreateOrUpdateInfo(form);
				this.save(form);
			}
		}
	}

	public boolean saveAndShowRelatedEntitiesChanged(WfBusTemplateForm form){
		boolean changed = false;
		if(form.getId() != null){
			WfBusTemplate entity = wfBusTemplateDao.get(form.getId());
			if(entity != null){
				if(entity.getMasterEntity() != null && entity.getSlaveEntities() != null){
					//如果修改了主、从实体
					if(!form.getMasterEntity().equals(entity.getMasterEntity()) || !form.getSlaveEntities().equals(entity.getSlaveEntities())){
						changed = true;
						wfViewConfigDao.deleteByTemplateId(form.getId());
					}
				}
				
			}
		}
		setCreateOrUpdateInfo(form);
		this.save(form);
		return changed;
	}
	
	/**
	 * 保存新增或修改的Form对象
	 */
	public void save(WfBusTemplateForm form){
		
		if(form != null){
			WfBusTemplate entity = null;
			
			//准备VO对象
			if(form != null && form.getId() != null){
				entity = wfBusTemplateDao.get(form.getId());
				
			}else{
				entity = new WfBusTemplate();
			}

			//属性值转换
			WfBusTemplateConvertor.convertFormToVo(form, entity);
			
			//设置业务流程模板的创建或者修改信息
			setCreateOrUpdateInfo(form);
			
			//保存
			wfBusTemplateDao.save(entity);
			
			//回填ID属性值
			form.setId(entity.getId());
		}
	}
	
	/**
	 * 保存新增或修改的Form对象
	 */
	public void saveBySmartForm(WfBusTemplateForm form){
		
		if(form != null){
			WfBusTemplate entity = null;
			
			//准备VO对象
			if(form != null && form.getId() != null){
				entity = wfBusTemplateDao.get(form.getId());
				
			}else{
				entity = new WfBusTemplate();
			}

			//属性值转换
			WfBusTemplateConvertor.convertFormToVoBySmartForm(form, entity);
			
			//设置业务流程模板的创建或者修改信息
			setCreateOrUpdateInfo(form);
			
			//保存
			wfBusTemplateDao.save(entity);
			
			//回填ID属性值
			form.setId(entity.getId());
		}
	}
	
	/**
	 * 设置业务流程模板的创建或者修改信息
	 */
	private void setCreateOrUpdateInfo(WfBusTemplateForm form){
		LoginUserForm user = (LoginUserForm)Struts2Utils.getSession().getAttribute(WebContextUtils.SES_LOGIN_USER);
		if(form.getId() != null){
			form.setUpdator(user.getUser().getLoginName());
			form.setUpdateTime(new Date());
		}
		else{
			form.setCreator(user.getUser().getLoginName());
			form.setCreateTime(new Date());
		}
	}

	/**
	 * 根据业务流程模板代码获取业务流程模板
	 * @param templateCode
	 * @return form
	 */
	@Transactional(readOnly = true)
	public WfBusTemplateForm getByTemplateCode(String templateCode){
		if(templateCode != null && templateCode.trim().length() > 0){
			String hql = GET_WHOLE_TEMPLATE_INFO + " and template.templateCode=?";
			Object[] objs = wfBusTemplateDao.findUnique(hql, templateCode);
			if(objs != null){
				WfBusTemplateForm form = WfBusTemplateConvertor.convertVoToForm((WfBusTemplate)objs[0]);
				form.setTemplateTypeName((String)objs[1]);
				return form;
			}
		}
		return null;
	}
	
	public WfBusTemplateForm getByWfDefKey(String wfDefKey){
		WfBusTemplate entity = wfBusTemplateDao.findUnique("from WfBusTemplate temp where temp.wfDefKey=?", wfDefKey);
		return WfBusTemplateConvertor.convertVoToForm(entity);
	}
	
	/**
	 * 删除模板对应的非公共页面元素
	 * @param tmeplateId
	 */
	public void deleteUnpublicElemsInCurTemplate(Long templateId){

		List<WfPageElement> elems = this.getUnpublicElemsInTemplate(templateId);
		
		//删除模板与页面元素对应的关联表
		wfTemplateElementRefDao.deleteRefByTemplateId(templateId);
		
		if(elems != null && elems.size() > 0)
			wfPageElementDao.delete(elems);
	}
	
	/**
	 * 获取模板下的非公有的页面元素
	 * @param templateId
	 * @return
	 */
	@Transactional(readOnly = true)
	public List<WfPageElement> getUnpublicElemsInTemplate(Long templateId){
		if(templateId != null){
			StringBuilder hql = new StringBuilder("select elem from WfPageElement elem, WfTemplateElementRef ref ");
			hql.append(" where elem.id = ref.elementId and elem.isPublic <> '1' and ref.templateId = ?");
			return wfPageElementDao.find(hql.toString(), templateId);
		}
		return null;
	}
	
	/**
	 * 分页获取不属于业务流程模板的公共页面元素
	 * @param templateId
	 * @param page
	 * @param form
	 * @return
	 */
	@Transactional(readOnly = true)
	public Page<WfPageElementForm> getPublicElementNotInTemplate(Long templateId, Page<WfPageElementForm> page, WfPageElementForm form){
		
		// 建立新的分页对象
		@SuppressWarnings(value={"unchecked"})
		Page<WfPageElement> pg = PageUtils.newPageInstance(page);
		
		List<Object> values = new ArrayList<Object>() ;
		
		StringBuilder hql = new StringBuilder("select elem1 ");
		hql.append(" from WfPageElement elem1");
		hql.append(" where elem1.isPublic = '1'");
		if(form != null){
			if(form.getElementCode() != null && form.getElementCode().trim().length() > 0){
				hql.append(" and elem1.elementCode like ?");
				values.add("%" + form.getElementCode() + "%");
			}
			if(form.getElementName() != null && form.getElementName().trim().length() > 0){
				hql.append(" and elem1.elementName like ?");
				values.add("%" + form.getElementName() + "%");
			}
		}
		
		hql.append(" and  elem1.id not in(");
		hql.append(" select elem.id ");
		hql.append(" from WfPageElement elem, WfTemplateElementRef ref ");
		hql.append(" where elem.id = ref.elementId and elem.isPublic = '1' ");
		hql.append("  and ref.templateId = ? )");
		values.add(templateId);
		
		wfPageElementDao.findPage(pg, hql.toString(), values);
		
		// 转换为Form对象列表并赋值到原分页对象中
		List<WfPageElementForm> list = WfPageElementConvertor.convertVoListToFormList(pg.getResult());
		PageUtils.copy(pg, list, page);
		return page;
	}
	
	
	/**
	 * 级联删除流程业务模板
	 * @param ids
	 */
	public void deleteCascade(Long... ids){
		if(ids != null && ids.length > 0){
			for(Long id: ids){
				deleteCascade(id);
			}
		}
		
	}
	
	
	/**
	 * 级联删除流程业务模板
	 * @param id
	 */
	public void deleteCascade(Long id){
		
		WfBusTemplate entity = wfBusTemplateDao.get(id);
		
		if(entity != null){
		
			//删除模板对应的流程结点权限信息
			wfActElemPrivDefDao.deleteElemPrivInTemplate(id);
			
			//删除模板对应的流程实例
			wfBusInstanceDao.deleteByTemplateId(id);
			
			//删除模板对应的视图配置
			wfViewConfigDao.deleteByTemplateId(id);
			
			//删除模板对应的附件表
			wfTemplateAttachmentRefService.deleteByTemplateId(id);
			
			//删除模板中非公共的页面元素
			deleteUnpublicElemsInCurTemplate(id);
			
			//删除JBPM所有版本的流程定义
			wfService.deleteProcDefByProcDefKey(entity.getWfDefKey());
			
			//删除模板本身
			wfBusTemplateDao.delete(entity);
		}
	}
	
	/**
	 * 根据模板类别获取流程业务模板列表
	 * @param templateType 模板类别
	 * @return 流程业务模板列表
	 */
	@Transactional(readOnly = true)
	public List<WfBusTemplateForm> getByTemplateTypeId(Long templateTypeId){
		String hql = "select template from WfBusTemplate template, WfBusTemplateType type where template.templateTypeId=type.id and type.id=?";
		List<WfBusTemplate> entities = wfBusTemplateDao.find(hql, templateTypeId);
		return WfBusTemplateConvertor.convertVoListToFormList(entities);
	}
	
	/**
	 * 删除指定模板类别的所有流程模板
	 * @param templateType
	 */
	public void deletByTemplateType(String templateType){
		List<WfBusTemplate>  entities = wfBusTemplateDao.findBy("templateType", templateType);
		if(entities != null && entities.size() > 0){
			for(WfBusTemplate entity:entities)
				this.deleteCascade(entity.getId());
		}
			
	}
	
	/**
	 * 根据Form对象的查询条件作分页查询
	 */
	@SuppressWarnings(value={"unchecked"})
	@Transactional(readOnly = true)
	public Page<WfBusTemplateForm> search(Page<WfBusTemplateForm> page, WfBusTemplateForm form) {
		// 建立新的分页对象
		
		Page pg = PageUtils.newPageInstance(page);
		
		// 查询语句及参数
		StringBuilder hql = new StringBuilder(GET_WHOLE_TEMPLATE_INFO);
		List<Object> values = new ArrayList<Object>();
		
		// 查询条件
		if(form != null){
			if(StringUtils.isNotBlank(form.getTemplateCode())){
				hql.append(" and template.templateCode like ?");
				values.add("%" + form.getTemplateCode() + "%");
			}
			if(StringUtils.isNotBlank(form.getTemplateName())){
				hql.append(" and template.templateName like ?");
				values.add("%" + form.getTemplateName() + "%");
			}
			if(StringUtils.isNotBlank(form.getWfDefKey())){
				hql.append(" and template.wfDefKey like ?");
				values.add("%" + form.getWfDefKey() + "%");
			}
			if(form.getTemplateTypeId() != null){
				hql.append(" and template.templateTypeId = ?");
				values.add(form.getTemplateTypeId());
			}
			if(StringUtils.isNotBlank(form.getIsActive())){
				hql.append(" and template.isActive = ?");
				values.add(form.getIsActive());
			}
			if(StringUtils.isNotBlank(form.getTemplateTypeName())){
				hql.append(" and type.templateTypeName like ?");
				values.add("%" + form.getTemplateTypeName() + "%");
			}
		}
		
		//排序
		hql.append(HqlUtils.buildOrderBy(page, "type.id"));
		
		// 执行分页查询操作
		wfBusTemplateDao.findPage(pg, hql.toString(), values);
		
		// 转换为Form对象列表并赋值到原分页对象中
		List<WfBusTemplateForm> list = WfBusTemplateConvertor.convertTo(pg.getResult());
		PageUtils.copy(pg, list, page);
		return page;
	}
	
	/**
	 * 根据过滤条件列表作分页查询
	 */
	@Transactional(readOnly = true)
	public Page<WfBusTemplateForm> search(Page<WfBusTemplateForm> page, List<PropertyFilter> filters) {
		// 建立新的分页对象
		@SuppressWarnings(value={"unchecked"})
		Page<WfBusTemplate> pg = PageUtils.newPageInstance(page);
		
		// 按过滤条件分页查找对象
		wfBusTemplateDao.findPage(pg, filters);
		
		// 转换为Form对象列表并赋值到原分页对象中
		List<WfBusTemplateForm> list = WfBusTemplateConvertor.convertVoListToFormList(pg.getResult());
		PageUtils.copy(pg, list, page);
		return page;
	}
	
	
	private Long countSqlResult(String sql, List<Object> values){
		String countSql = "select count(*) from (" + StringUtils.substringBefore(sql, "order by") + ")";
		try {
			Query query = wfPageElementDao.getSession().createSQLQuery(countSql);			
			if(values != null && values.size() > 0){
				for(int i = 0; i < values.size(); i++){
					query.setParameter(i, values.get(i));
				}				
			}
			BigDecimal obj = (BigDecimal)query.uniqueResult();
			return obj.longValue();
		} catch (Exception e) {
			throw new RuntimeException("sql can't be auto count, sql is:" + countSql, e);
		}
	}
	
	/**
	 * 分页获取指定流程业务模块下的页面元素
	 * @param page 
	 * @param templateId 
	 * @return
	 */
	@SuppressWarnings(value={"unchecked"})
	@Transactional(readOnly = true)
	public Page<WfPageElementForm> getPageElemByTemplateId(Page<WfPageElementForm> page, Long templateId){
		if(templateId != null){
			StringBuilder sql = new StringBuilder("select elem.*, parent.element_code as parentElementCode");
			sql.append(" from wf_page_element elem");
			sql.append(" inner join  wf_template_element_ref ref");
			sql.append(" on elem.id = ref.element_id and ref.template_id =?");
			sql.append(" left join wf_page_element parent on elem.parent_id = parent.id");
			sql.append(" order by elem.element_type asc, elem.element_group asc, elem.group_sort_no asc, elem.element_sort_no asc");
			
			List<Object> values = new ArrayList<Object>();
			values.add(templateId);
			
			//设置总记录条数
			page.setTotalCount(countSqlResult(sql.toString(), values));
			
			SQLQuery sqlQuery = wfPageElementDao.getSession().createSQLQuery(sql.toString());
			sqlQuery.addEntity(WfPageElement.class).addScalar("parentElementCode");
			sqlQuery.setFirstResult(page.getFirst() - 1);
			sqlQuery.setMaxResults(page.getPageSize());
			sqlQuery.setParameter(0, templateId);
			
			List<Object[]> objsList = sqlQuery.list();
			
			//转换查询结果
			List<WfPageElementForm> result = null;
			if(objsList != null && objsList.size() > 0){
				result = new ArrayList<WfPageElementForm>();
				for(int i = 0; i < objsList.size(); i++){
					Object[] objs = objsList.get(i);
					WfPageElementForm form = WfPageElementConvertor.convertVoToForm((WfPageElement)objs[0]);
					form.setParentElementCode((String)objs[1]);
					result.add(form);
				}
			}
			
			page.setResult(result);
			return page;
		}
		return null;
	}
	
	/**
	 * 获取模板中字段类型页面元素的elementId的列表
	 * @param templateId
	 * @return
	 */
	@Transactional(readOnly = true)
	public List<String> getFieldTypeElementIdInTemplate(Long templateId){
		if(templateId != null){
			StringBuilder hql = new StringBuilder("select elem.elementCode from WfTemplateElementRef ref, WfPageElement elem");
			hql.append(" where ref.elementId=elem.id");
			hql.append(" and ref.templateId=?");
			hql.append(" and elem.elementType='field'");
			return wfPageElementDao.find(hql.toString(), templateId);
		}
		return null;
	}
	
	public Page<WfActElemPrivDefForm> getContainElemWithPriv(Page<WfActElemPrivDefForm> page, WfActElemPrivDefForm form){
		return this.getElemWithPrivByType(WfPageElementForm.CONTAIN_ELEM_TYPE, page, form);
	}
	public Page<WfActElemPrivDefForm> getButtonElemWithPriv(Page<WfActElemPrivDefForm> page, WfActElemPrivDefForm form){
		return this.getElemWithPrivByType(WfPageElementForm.BUTTON_ELEM_TYPE, page, form);
	}
	
	
	public Page<WfActElemPrivDefForm> getElemWithPrivByType(String elemType, Page<WfActElemPrivDefForm> page, WfActElemPrivDefForm form){
		String loadElemByTypeSql = "";
		StringBuilder sql = new StringBuilder();
		if(elemType.equals(WfPageElementForm.FIELD_ELEM_TYPE)){
			loadElemByTypeSql = WfPageElementServiceImpl.SQL_LOAD_FIELD_ELEMS;
		}
		else if(elemType.equals(WfPageElementForm.BUTTON_ELEM_TYPE)){
			loadElemByTypeSql = WfPageElementServiceImpl.SQL_LOAD_BUTTON_ELEMS;
		}
		else if(elemType.equals(WfPageElementForm.CONTAIN_ELEM_TYPE)){
			loadElemByTypeSql = (WfPageElementServiceImpl.SQL_LOAD_CONTAIN_ELEMS);
		}
		// 广州城管委行政审批修改 开始
		else if(elemType.equals(WfPageElementForm.PRINT_ELEM_TYPE)){
            sql.append("select priv.*, elem.id as elemId, elem.file_code as code, elem.file_name as name ");
            sql.append("  from WF_TEMPLATE_ATTACHMENT_REF elem, ");
            sql.append("       (select * from WF_ACT_PRINTTPL_PRIV_DEF where version = '" + form.getVersion() + "' and view_name = '" + form.getViewName() + "' and template_id = " + form.getTemplateId());
            if(form.getViewName().equals(WfActElemPrivDefForm.DB_ZB_VIEW)){
                sql.append(" and activity_name = '" + form.getActivityName() + "' ");
            }
            sql.append(" ) priv ");
            sql.append(" where elem.id = priv.element_id(+) ");
            sql.append("   and (elem.file_type = '1' or elem.file_type = '2') ");
            sql.append("   and elem.template_id = " + form.getTemplateId() + " order by elem.file_type, elem.id");
        }
		// 广州城管委行政审批修改 结束
		else{
			throw new IllegalArgumentException("No exist " + elemType + "page elment!");
		}
		
		List<Object> values = new ArrayList<Object>();
		
		// 广州城管委行政审批修改 开始
		if(!elemType.equals(WfPageElementForm.PRINT_ELEM_TYPE)) {
			sql.append("select priv.*, elem.id as elemId, elem.element_code as code, elem.element_name as name");
			sql.append(" from wf_page_element elem"); 
			sql.append(" inner join wf_template_element_ref ref  on elem.id = ref.element_id and ref.template_id=? ");
			sql.append(loadElemByTypeSql);
			sql.append(" left join wf_act_elem_priv_def priv on elem.id = priv.element_id");
			sql.append(" and priv.version =? and priv.view_name =? and priv.template_id=? ");
			
			values.add(form.getTemplateId());
			values.add(form.getVersion());
			values.add(form.getViewName());
			values.add(form.getTemplateId());
			if(form.getViewName().equals(WfActElemPrivDefForm.DB_ZB_VIEW)){
				sql.append(" and priv.activity_name =? ");
				values.add(form.getActivityName());
			}
			sql.append("order by elem.element_code");
		}
		// 广州城管委行政审批修改 结束
		
		page.setTotalCount(this.countSqlResult(sql.toString(), values));
		
		SQLQuery query = wfActElemPrivDefDao.getSession().createSQLQuery(sql.toString());
		query.setFirstResult(page.getFirst() - 1);
		query.setMaxResults(page.getPageSize());
		
		// 广州城管委行政审批修改 开始
		if(!elemType.equals(WfPageElementForm.PRINT_ELEM_TYPE)) {
		    query.addEntity(WfActElemPrivDef.class).addScalar("elemId").addScalar("code").addScalar("name");
		} else {
		    query.addEntity(WfActPrinttplPrivDef.class).addScalar("elemId").addScalar("code").addScalar("name");
		}
		// 广州城管委行政审批修改 结束
		
		for(int i = 0; i < values.size(); i++){
			query.setParameter(i, values.get(i));
		}
		
		@SuppressWarnings(value={"unchecked"})
		List<Object[]> objsList = (List<Object[]>)query.list();
		
		List<WfActElemPrivDefForm> result = null;
		if(objsList != null && objsList.size() > 0){
			result = new ArrayList<WfActElemPrivDefForm>();
			for(int i = 0; i < objsList.size(); i++){
				// 广州城管委行政审批修改 开始
				WfActElemPrivDefForm privForm = null;
                
                if(!elemType.equals(WfPageElementForm.PRINT_ELEM_TYPE)) {
                    WfActElemPrivDef priv = (WfActElemPrivDef)objsList.get(i)[0];
                    if(priv != null) privForm = WfActElemPrivDefConvertor.convertVoToForm(priv);
                } else {
                	WfActPrinttplPrivDef priv = (WfActPrinttplPrivDef)objsList.get(i)[0];
                    if(priv != null) privForm = WfActPrinttplPrivDefConvertor.convertVoToFkForm(priv);
                }
				
				if (privForm == null) {
					privForm = new WfActElemPrivDefForm();
					privForm.setHidden(false);
					privForm.setLocked(false);
					
					privForm.setId(Long.parseLong(objsList.get(i)[1].toString()));
					privForm.setTemplateId(form.getTemplateId());
					privForm.setVersion(form.getVersion());
					privForm.setViewName(form.getViewName());
					privForm.setActivityName(form.getActivityName());
				}
				// 广州城管委行政审批修改 结束
				
				privForm.setElementId(Long.parseLong(objsList.get(i)[1].toString()));
				if(privForm.getElementId().equals(-3L)){
					System.out.println(privForm.getTemplateId());
				}
				// 广州城管委行政审批修改 开始
				privForm.setElementType(elemType);
				// 广州城管委行政审批修改 结束
				privForm.setElementCode((String)objsList.get(i)[2]);
				privForm.setElementName((String)objsList.get(i)[3]);
				result.add(privForm);
			}
		}
		page.setResult(result);
		return page;
	}
	/**
	 * 分页获取字段类型的页面元素（带权限控制信息）
	 * @param page
	 * @param form
	 * @return
	 */
	public Page<WfActElemPrivDefForm> getFieldElemWithPriv(Page<WfActElemPrivDefForm> page, WfActElemPrivDefForm form){
		return this.getElemWithPrivByType(WfPageElementForm.FIELD_ELEM_TYPE, page, form);
	}
	
	/**
	 * 分页分类获取业务流程模板下页面元素
	 * @param page
	 * @param templateId
	 * @param elemType
	 * @return
	 */
	@Transactional(readOnly = true)
	public Page<WfPageElementForm> getPageElemInTemplateByType(Page<WfPageElementForm> page, Long templateId, String elemType){
		
		// 建立新的分页对象
		@SuppressWarnings(value={"unchecked"})
		Page<WfPageElement> pg = PageUtils.newPageInstance(page);
		
		List<Object> values = new ArrayList<Object>();
		
		StringBuilder hql = new StringBuilder("select elem");
		hql.append(" from WfTemplateElementRef ref, WfPageElement elem");
		hql.append(" where elem.id=ref.elementId");
		hql.append(" and ref.templateId=?");
		values.add(templateId);
		
		if(elemType.equalsIgnoreCase(WfPageElementForm.CONTAIN_ELEM_TYPE)){
			hql.append(" and (");
			for(int i = 0; i < WfPageElementForm.childElemsInContain.length; i++){
				if(i == 0)
					hql.append(" elem.elementType=?");
				else
					hql.append(" or elem.elementType=?");
				values.add(WfPageElementForm.childElemsInContain[i]);
			}
			hql.append(" )");
		}
		else{
			hql.append(" and elem.elementType=?");
			values.add(elemType);
		}
		
		hql.append(" order by elem.elementCode");
		wfPageElementDao.findPage(pg, hql.toString(),values);
		
		
		// 转换为Form对象列表并赋值到原分页对象中
		List<WfPageElementForm> list = WfPageElementConvertor.convertVoListToFormList(pg.getResult());
		PageUtils.copy(pg, list, page);
		return page;
	}
	
	/**
	 * 分类获取业务流程模板下页面元素
	 * @param templateId
	 * @param elemType
	 * @param groupSort
	 * @return
	 */
	@Transactional(readOnly = true)
	public List<WfPageElementForm> getElementsByType(Long templateId, String elemType, boolean groupSort){
		StringBuilder hql = new StringBuilder(GET_ELEMENTS_BY_TYPE);
		hql.append(" and temp.id=?");
		hql.append(WfUtils.getPageElementsOrderClause("elem", groupSort));
		
		List<WfPageElement> entities = wfPageElementDao.find(hql.toString(), elemType, templateId);
		return WfPageElementConvertor.convertVoListToFormList(entities);
	}
	
	@Transactional(readOnly = true)
	public List<WfPageElementForm> getElementsByType(String templateCode, String elemType, boolean groupSort){
		StringBuilder hql = new StringBuilder(GET_ELEMENTS_BY_TYPE);
		hql.append(" and temp.templateCode=?");
		hql.append(WfUtils.getPageElementsOrderClause("elem", groupSort));
		
		List<WfPageElement> entities = wfPageElementDao.find(hql.toString(), elemType, templateCode);
		return WfPageElementConvertor.convertVoListToFormList(entities);
	}
	
	/**
	 * 设置元素权限信息
	 * @param elements
	 * @param templateId
	 * @param activityName
	 */
	private List<WfPageElementForm> setElemPrivInfo(List<WfPageElementForm> elements, Long templateId, Integer version, String viewName, String activityName){
		List<WfPageElementForm> result = new ArrayList<WfPageElementForm>();
		//设置权限信息
		if(elements != null && elements.size() > 0){
			List<WfActElemPrivDefForm> elemPrivDef = wfActElemPrivDefService.getElemPrivDef(templateId, version, viewName, activityName);
			
			for(WfPageElementForm element: elements){
				
				if(elemPrivDef != null && elemPrivDef.size() > 0){
					int i;
					for(i = 0; i < elemPrivDef.size(); i++){
						if(element.getId().equals(elemPrivDef.get(i).getElementId())){
							break;
						}
					}
					
					if(i < elemPrivDef.size()){
						if(!elemPrivDef.get(i).isHidden()){
							element.setHidden(elemPrivDef.get(i).isHidden());
							element.setLocked(elemPrivDef.get(i).isLocked());
							result.add(element);
						}
					}
					else{
						result.add(element);
					}
				}
				else{
					result.addAll(elements);
					break;
				}
			}
		}
		return result;
	}
	
	
	/**
	 * 按照类型获取业务流程某一个流程节点下某一类流程节点的权限信息
	 * @param elemType
	 * @param instance
	 * @param groupSort 
	 * @return
	 */
	@Transactional(readOnly = true)
	public List<WfPageElementForm> getElementsWithPrivByType(String elemType, WfBusInstanceTaskForm instance, boolean groupSort){	
		WfBusTemplateForm form = this.getByTemplateCode(instance.getTemplateCode());
		
		if(form != null){
			List<WfPageElementForm> elements = this.getElementsByType(form.getId(), elemType, groupSort);
			return setElemPrivInfo(elements, form.getId(), instance.getVersion(), instance.getViewName(), instance.getActivityName());
		}
		return null;
	}
	
	/**
	 * 获取业务流程某一个流程节点下指定版本下指定视图下某一流程节点的权限信息
	 * @param templateId
	 * @param version
	 * @param viewName
	 * @param activityName
	 * @return
	 */
	@Transactional(readOnly = true)
	public List<WfActElemPrivDefForm> getElemPrivDef(Long templateId, Integer version, String viewName, String activityName){
		if(templateId != null){
			return wfActElemPrivDefService.getElemPrivDef(templateId, version, viewName, activityName);
		}
		return null;
	}
	
	
	
	/**
	 * 获取页面元素在流程节点中的权限信息
	 * @param page 分页对象
	 * @param form 包含了templateId, version, viewName, activityName参数
	 * @return
	 */
	
	@Transactional(readOnly = true)
	public Page<WfActElemPrivDefForm> getPageElemWithPriv(Page<WfActElemPrivDefForm> page, WfActElemPrivDefForm form){
		@SuppressWarnings(value={"unchecked"})
		Page pg = PageUtils.newPageInstance(page);
		
		//根据类型获取模板下所有的页面元素
		Page<WfPageElementForm> pageElems = getPageElemInTemplateByType(pg, form.getTemplateId(), form.getElementType());
		
		//获取业务流程模板下指定版本、指定视图、指定节点的权限控制定义信息
		List<WfActElemPrivDefForm> elemPrivDef = wfActElemPrivDefService.getElemPrivDef(form.getTemplateId(), form.getVersion(), form.getViewName(), form.getActivityName());
		
		//转换
		if(pageElems.getResult() != null && pageElems.getResult().size() > 0){
			return WfActElemPrivDefConvertor.convertPageElemsToPageActElems(pageElems, elemPrivDef, form);
		}
		return null;
	}
	
	/**
	 * 删除模板中页面元素（注意：有两种情况：对于非公有页面元素，删除页面元素及关联；对于公有页面元素，删除模板与页面元素的关联） 
	 * @param tempalteId 模板id
	 * @param pageElementIds 页面元素
	 */
	public void deletePageElemFromTemplate(Long templateId, Long... pageElementIds){
		if(pageElementIds != null && pageElementIds.length > 0){
			for(Long elementId:pageElementIds){
				WfPageElementForm pageElem = wfPageElementService.get(elementId);
				
				//删除页面元素与模板的关联
				WfTemplateElementRef entity = wfTemplateElementRefDao.get(templateId, pageElem.getId());
				if(entity != null)
					wfTemplateElementRefDao.delete(entity);
				
				wfActElemPrivDefService.deleteByElemPrivInTemplate(templateId, pageElem.getId());
				
				//删除非公有页面元素
				if(pageElem.getIsPublic() == null || pageElem.getIsPublic().equals(WfPageElementForm.NOT_PUBLIC)){
					wfPageElementDao.delete(pageElem.getId());
				}
			}
		}
	}
	
	/**
	 * 获取指定模板指定流程节点下，元素Code为parentElementCode没有权限隐藏的孩子元素
	 * @param parentElementCode
	 * @param instance
	 * @return
	 */
	public List<WfPageElementForm> getNotHiddenChildElementsByGroup(String parentElementCode, WfBusInstanceTaskForm instance){
		WfPageElementForm parentElem = wfPageElementService.getByElementCode(parentElementCode);
		if(StringUtils.isNotBlank(instance.getTemplateCode())  && instance.getVersion() != null && StringUtils.isNotBlank(instance.getViewName())){
			//获取流程模板
			StringBuilder hql = new StringBuilder();
			List<Object> values = new ArrayList<Object>();
			
			Long templateId = this.getByTemplateCode(instance.getTemplateCode()).getId();
			hql.append("select elem from WfPageElement elem, WfTemplateElementRef ref");
			hql.append(" where elem.id=ref.elementId and elem.parentId = ? and  ref.templateId = ? and elem.id not in (");
			hql.append(" select priv.elementId ");
			hql.append(" from WfActElemPrivDef priv ");
			hql.append(" where priv.isHidden = '1' and priv.templateId = ?");
			hql.append(" and priv.version = ? and priv.viewName = ? ");
			
			//如果是待办、在办视图
			if(instance.getViewName().equals(WfPrivControlForm.DB_ZB_VIEW)){
				hql.append(" and priv.activityName = ?");
			}
			
			hql.append(") order by elem.groupSortNo asc, elem.elementSortNo asc");
			
			values.add(parentElem.getId());
			values.add(templateId);
			values.add(templateId);
			values.add(instance.getVersion());
			values.add(instance.getViewName());
			if(instance.getViewName().equals(WfPrivControlForm.DB_ZB_VIEW)){
				values.add(instance.getActivityName());
			}
			
			
			List<WfPageElement> entities = wfPageElementDao.find(hql.toString(), values);
			return WfPageElementConvertor.convertVoListToFormList(entities);
		}
		return null;
	}
	
	/**
	 * 根据权限控制信息获取某一个parentElementCode下的孩子元素
	 * @param parentElementCode 父元素Code
	 * @param instance
	 * @return
	 */
	@Transactional(readOnly = true)
	public List<WfPageElementForm> getChildElementsWithPriv(String parentElementCode, WfBusInstanceTaskForm instance){
		List<WfPageElementForm> childElements = this.getNotHiddenChildElementsByGroup(parentElementCode, instance);
		
		if(childElements != null && childElements.size() > 0){
			//获取流程模板
			WfBusTemplateForm form = this.getByTemplateCode(instance.getTemplateCode());
			
			if(form != null){
				//获取流程节点下所有的权限配置信息
				List<WfActElemPrivDefForm> elemsWithPriv = wfActElemPrivDefService.getElemPrivDef(form.getId(), instance.getVersion(), instance.getViewName(), instance.getActivityName());
				
				if(elemsWithPriv != null && elemsWithPriv.size() > 0){
					for(WfPageElementForm pageElem:childElements){
						
						for(WfActElemPrivDefForm priv:elemsWithPriv){
							//如果页面元素在指定流程节点具有权限配置信息
							if(pageElem.getId().equals(priv.getElementId())){
								pageElem.setLocked(priv.isLocked());
							}
						}
					}
				}
			}
		}
		return childElements;
	}
	
	/**
	 * 导入字段到业务流程模板
	 * @param tempalteId 模板id
	 * @param filedsNeedToBeImported 需要导入的字段列表
	 * @param fieldsComments 字段对应的注释
	 */
	public void importFieldsToBusTemplate(Long templateId, List<String> filedsNeedToBeImported, Map<String, String> fieldsComments){
		for(String field: filedsNeedToBeImported){
			
			WfPageElementForm form = wfPageElementService.getByElementCode(field);
			
			//如果数据表中没有该页面元素
			if(form == null){
				form = new WfPageElementForm();
				form.setTemplateId(templateId);
				form.setElementCode(field);
				form.setElementType(WfPageElementForm.FIELD_ELEM_TYPE);
				form.setElementName(fieldsComments.get(field));
				form.setIsPublic(WfPageElementForm.NOT_PUBLIC);
			}
			
			wfPageElementService.addPageElement(form);
		}
	}
	
	/**
	 * 删除业务流程模板中已有的字段
	 * @param tempalteId 模板id
	 * @param fieldsNeededToBeDeleted 需要删除的字段列表
	 */
	public void deleteFieldsFromBusTemplate(Long templateId, List<String> fieldsNeededToBeDeleted){
		List<WfPageElementForm> list = wfPageElementService.batchGetByElementIds(fieldsNeededToBeDeleted);
		for(WfPageElementForm pageElemForm:list){
			this.deletePageElemFromTemplate(templateId, pageElemForm.getId());
		}
	}
	
	@Transactional(readOnly = true)
	public List<WfBusTemplateForm> getAllActive(){
	    //    zhuhx add //
	    //String hql = GET_WHOLE_TEMPLATE_INFO + " and template.isActive=? order by template.memo";
		String hql = GET_WHOLE_TEMPLATE_INFO + " and template.isActive=? order by template.memo,template.id";
		//	  zhuhx end //
		List<Object[]> list = wfBusTemplateDao.find(hql, OrgConstant.ONE);
		if(list != null && list.size() > 0){
			List<WfBusTemplateForm> result = new ArrayList<WfBusTemplateForm>();
			
			for(Object[] objs : list){
				WfBusTemplateForm form = WfBusTemplateConvertor.convertVoToForm((WfBusTemplate)objs[0]);
				form.setTemplateTypeName((String)objs[1]);
				result.add(form);
			}
			
			return result;
		}
		return null;
	}
	
	/**
	 * 获取打印模板
	 * @param templateCode
	 * @return
	 */
	public String getPrintTemplatePath(String templateCode){
		return wfTemplateAttachmentRefService.getPrintTemplatePath(templateCode);
	}
	
	@Transactional(readOnly = true)
	public List<SysMetaTableForm> getRelateEntities(Long templateId){
		WfBusTemplateForm form = this.get(templateId);
		if(form != null){
			
			String[] realatedEEntityNames = null;
			if(form.getSlaveEntities() != null && form.getSlaveEntities().trim().length() > 0){
				String realatedEEntities = form.getMasterEntity() + WfBusTemplateForm.SLAVE_ENTITY_SEPARATOR + form.getSlaveEntities();
				realatedEEntityNames = realatedEEntities.split(WfBusTemplateForm.SLAVE_ENTITY_SEPARATOR);
			}
			else{
				realatedEEntityNames = new String[1]; 
				realatedEEntityNames[0] = form.getMasterEntity();
			}
			return sysMetaTableService.getTableByTableNames(realatedEEntityNames);
		}
		return null;
	}
	
	@Transactional(readOnly = true)
	public List<SysMetaTableForm> getSlaveEntities(Long templateId){
		WfBusTemplateForm form = this.get(templateId);
		if(form != null){
			if(form.getSlaveEntities() != null && form.getSlaveEntities().trim().length() > 0){
				String[] slaveEntityNames = form.getSlaveEntities().split(WfBusTemplateForm.SLAVE_ENTITY_SEPARATOR);
				return sysMetaTableService.getTableByTableNames(slaveEntityNames);
			}
		}
		return null;
	}
	
	public List<SysMetaTableForm> selectSlaveEntitiesByMasterEntity(SysMetaTableForm form, String masterEntity){
		return sysMetaTableService.getOtherTables(form, masterEntity);
	}
	
	/**
	 * 更新模板，并导入权限
	 * @param wfService WfServiceImpl
	 * @param templateId 模板id
	 * @param curProcessDef 当前最新发布版本的流程定义
	 */
	public void updateVersionAndImportPriv(IWfService wfService, Long templateId, ProcessDefinitionImpl curProcessDef){
		WfBusTemplateForm template  = this.get(templateId);
		if(template == null){
			throw new NullPointerException("Can't find the template by " + templateId);
		}
		
		//是否有上一个版本
		if(template.getWfDefKey() != null && template.getWfDefVersion() != null){
			
			ProcessDefinitionImpl preProcessDef = (ProcessDefinitionImpl)wfService.getProcDefByProcDefKeyAndVersion(template.getWfDefKey(), template.getWfDefVersion());
			if(preProcessDef == null){
				throw new NullPointerException("Can't find the the process definition by key: " + template.getWfDefKey() + " and version:" + template.getWfDefVersion());
			}
			
			List<String> commonActivities = WfUtils.getCommonActivityNames(curProcessDef.getActivities(), preProcessDef.getActivities());
			
			if(commonActivities != null && commonActivities.size() > 0){
				//导入上一个版本的待办、在办公共结点的权限
				wfActElemPrivDefService.importDbZbViewPrivFromPreVersion(templateId, curProcessDef.getVersion(), preProcessDef.getVersion(), commonActivities);
			}
			//导入上一个版本的已办、办结的权限
			wfActElemPrivDefService.importYbBjViewPrivFromPreVersion(templateId, curProcessDef.getVersion(), preProcessDef.getVersion());
		}
		
		
		//更新模板的版本
		template.setWfDefKey(curProcessDef.getKey());
		template.setWfDefVersion(curProcessDef.getVersion());
		this.save(template);
		
	}
}
